#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<cmath>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int inf=1012345678;
#define clr(x,a) memset(x,a,sizeof(x))


inline int rd(){int x;scanf("%d",&x);return x;}
const int maxn =  40000;
const int maxe = 101000;
int n,m;
int nodeval[maxe],first[maxe],next[maxe],E[maxe],M;
void init()
{
	M=0;
	for(int i=0; i<=n+3; i++)
		first[i]=-1;
}
void _ins(int a,int b)
{
	M++;
	next[M]=first[a];
	first[a]=M;
	E[M]=b;
}
void ins(int a,int b)
{
	_ins(a,b);
	_ins(b,a);
}

struct node
{
	int a,add,maxx,sum;
}qtr[maxe*4],*tl,*head[maxe];
int trsz[maxe],cas,dep[maxe],belong[maxe],pos[maxe],vis[maxe],son[maxn];
int rmq[maxn][20],LOG=16;

void pushup(node*tr,int nod)
{
	tr[nod].sum=tr[nod<<1].sum+tr[nod<<1|1].sum;
	tr[nod].maxx=max(tr[nod<<1].maxx,tr[nod<<1|1].maxx);
}

void insert(node *tr,int nod,int l,int r,int x,int y,int a)
{//把值x到y的值改成a
	if(l==r)
	{
		tr[nod].a=tr[nod].maxx=tr[nod].sum=a;
		return ;
	}
	int mid=(l+r)/2;
	if(x<=mid)
		insert(tr,nod<<1,l,mid,x,y,a);
	if(mid<y)
		insert(tr,nod<<1|1,mid+1,r,x,y,a);
	pushup(tr,nod);
}
void maketree(int u,int h)
{
	int i,rt=u;
	for(i=1; i<h; i++)	rt=rmq[rt][0];//找到根 
	head[rt]=tl;
	for(i=0; i<h*4; i++)//初始话树
	 head[rt][i].a=head[rt][i].add=head[rt][i].sum=head[rt][i].maxx=0;
		
	tl+=h*4;//偏移量加值
	trsz[rt]=h;//记录这颗树有多少个元素
	for(i=h; i>=1; i--)
	{
		belong[u]=rt;//当前节点属于那棵树
		pos[u]=i;//当前节点所在的这颗树第几个元素
		insert(head[rt],1,1,h,i,i,nodeval[u]);
		u=rmq[u][0];
	}
}
void change(int x,int y)
{
	int fa=belong[x];
	nodeval[x]=y;
	insert(head[fa],1,1,trsz[fa],pos[x],pos[x],y);
}

int findsum(node*tr,int nod,int l,int r,int x,int y)
{
	if(x<=l && r<=y)
		return tr[nod].sum;
	int mid=(l+r)/2,ans=0;
	if(x<=mid)
		ans+=findsum(tr,nod<<1,l,mid,x,y);
	if(mid<y)
		ans+=findsum(tr,nod<<1|1,mid+1,r,x,y);
	pushup(tr,nod);
	return ans;
}

int getsum(int a,int b,int &is)
{
	int ans=0,fa,fb;
	is=0;
	while(a!=b)
	{
		fa=belong[a]; fb=belong[b];
		if(fa!=fb)
		{
			ans+=findsum(head[fb],1,1,trsz[fb],1,pos[b]);
			b=rmq[fb][0];
		}
		else
		{
			is=1;
			ans+=findsum(head[fb],1,1,trsz[fb],pos[a],pos[b]);
			break;
		}
	}
	return ans;
}

int findmax(node*tr,int nod,int l,int r,int x,int y)
{
	if(x<=l && r<=y)
		return tr[nod].maxx;
	int mid=(l+r)/2,ans=-inf;
	if(x<=mid)
		ans=max(ans,findmax(tr,nod<<1,l,mid,x,y));
	if(mid<y)
		ans=max(ans,findmax(tr,nod<<1|1,mid+1,r,x,y));
	pushup(tr,nod);
	return ans;
}
int getmax(int a,int b)
{
	if(a==b)	return nodeval[a];
	int ans=-inf,fa,fb;
	while(a!=b)
	{
		fa=belong[a],fb=belong[b];
		if(fa!=fb)
		{
			ans=max(ans,findmax(head[fb],1,1,trsz[fb],1,pos[b]));
			b=rmq[fb][0];
		}
		else
		{
			ans=max(ans,findmax(head[fb],1,1,trsz[fb],pos[a],pos[b]));
			break;
		}
	}
	return ans;
}

void dfs1(int u)
{
	int i,j,e;
	vis[u]=cas;
	for(i=1; i<LOG; i++) rmq[u][i]=rmq[rmq[u][i-1]][i-1];
	son[u]=1;
	for(e=first[u]; e!=-1; e=next[e])
	if(vis[E[e]]<cas)
	{
		int v=E[e];
		dep[v]=dep[u]+1;
		rmq[v][0]=u;
		dfs1(v);
		son[u]+=son[v];
	}
}
void dfs2(int u,int h)//第二次dfs划分轻重边
{
	int i,j,e,v;
	vis[u]=cas;
	int now=-1,tp=0;
	for(e=first[u]; e!=-1; e=next[e])
	if(vis[E[e]]<cas && tp <son[E[e]])//找重边
	{
		tp=son[E[e]];
		now=E[e];
	}
	if(now==-1)//找到一条重边的节点,建立线段树
	{
		maketree(u,h);
		return ;
	}
	dfs2(now,h+1);//找下一条重边
	for(e=first[u];e!=-1 ; e=next[e])
	{
		v=E[e];
		if(vis[v]<cas && v!=now)
			dfs2(v,1);
	}
}
void split(int rt)//两次深搜进行重边划分
{
	tl=qtr;//头赋值
	cas++;
	dep[rt]=1;//根节点
	memset(rmq,0,sizeof(rmq));
	dfs1(rt);
	cas++;
	dfs2(rt,1);
}
int lca(int a,int b)
{//算出a 和b的公共祖先
	int i,tp=dep[b]-dep[a];
	if(tp<0)
	{
		tp=-tp;
		swap(a,b);
	}
	for(i=0; i<LOG; i++)
	if(tp&(1<<i))	b=rmq[b][i];
	if(a==b)	return a;
	for(i=LOG; i>=0; i--)
	if(rmq[a][i]!=rmq[b][i])
	{
		a=rmq[a][i];
		b=rmq[b][i];
	}
	return rmq[a][0];
}
int main()
{
 
    int i,j,k,p;
	while(scanf("%d",&n)!=EOF)
	{
		int x,y,z;
		init();
		for(i=1; i<n; i++)
		{
			scanf("%d%d",&x,&y);
			ins(x,y);
		}
		for(i=1; i<=n; i++)
			nodeval[i]=rd();
		
		split(1);
		scanf("%d",&m);
		int fa,h1,h2,ans;
		char ch[20];
		for(i=0; i<m; i++)
		{
			scanf(" %s%d%d",ch,&x,&y);
			fa=lca(x,y);
			if(ch[1]=='H')
			{
				change(x,y);
			}
			else if(ch[1]=='S')
			{
				ans=getsum(fa,x,h1)+getsum(fa,y,h2);
				if(h1==0 && h2==0)
					ans+=nodeval[fa];		
				printf("%d\n",ans);
			}
			else
			{
				ans=max(getmax(fa,x),getmax(fa,y));
				ans=max(ans,nodeval[fa]);
				printf("%d\n",ans);
			}
		}
	}
}
